package com.cloud.example.business.async.service.impl;

import com.alibaba.fastjson.JSON;
import com.cloud.async.business.context.support.StandardAsyncContext;
import com.cloud.example.business.async.entity.Car;
import com.cloud.example.business.async.service.AsyncService;
import com.cloud.example.business.async.service.CalledAsyncService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * @author chengrui
 */
@Service
public class AsyncServiceImpl implements AsyncService {
    /**
     * logger
     */
    private final Log logger = LogFactory.getLog(getClass());

    @Autowired
    CalledAsyncService calledAsyncService;

    @Autowired
    StandardAsyncContext standardAsyncContext;

    @Override
    public String testAsync() {
        String name = "";

        long startTime = System.currentTimeMillis();

        //涉及相应调用（模拟调用且有3s时间等待业务操作）
        //本身实现等同于example1() 方法见下
        String calledAsyncKey = standardAsyncContext.doBusiness(() -> calledAsyncService.calledAsync(name));

        //假设执行业务
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (Exception e) {

        }

        // ================结果处理（返回值一定要是String）================
        //================获取原生为string的结果================
        //执行完成之后就会进行删除当前的key（calledAsyncKey）
        //默认延时 milliSecond = 0；在配置类中可以进行配置真特的
        //String result = applicationAsyncContext.getResult(calledAsyncKey);
        //ret:{"age":22,"car":{"carName":"吉利帝豪","color":"blue","useAge":2},"carName":"吉利帝豪","name":"chengr"}
        //logger.info("ret:" + result);

        //如果调用任务所需时间较长，可以使用如下方法  milliSecond不会影响整体的配置类的设置
        //String result1 = applicationAsyncContext.getResult(calledAsyncKey, 5000L);
        //ret:{"age":22,"car":{"carName":"吉利帝豪","color":"blue","useAge":2},"carName":"吉利帝豪","name":"chengr"}
        //logger.info("ret:" + result1);

        //================返回值为一个对象================
        //执行完成之后就会进行删除当前的key（calledAsyncKey）
        //Person result2 = applicationAsyncContext.getResult(Person.class, calledAsyncKey);
        //ret [{}]:Person{name='chengr', age=22, carName='吉利帝豪', car=Car{carName='吉利帝豪', useAge=2, color='blue'}}
        //logger.info("ret [{}]:" + result2);

        //如果调用任务所需时间较长，可以使用如下方法
        //Person result3 = applicationAsyncContext.getResult(Person.class, calledAsyncKey,5000L);
        //ret [{}]:Person{name='chengr', age=22, carName='吉利帝豪', car=Car{carName='吉利帝豪', useAge=2, color='blue'}}
        //logger.info("ret [{}]:" + result3);

        //================返回json字符串中的对象的对象================
        //Car car = applicationAsyncContext.getResult(Car.class, calledAsyncKey, "car");
        //ret [{}]:Car{carName='吉利帝豪', useAge=2, color='blue'}
        //logger.info("ret [{}]:" + car);

        //此方法计划废弃
        //Car car1 = standardAsyncContext.getResult(Car.class, calledAsyncKey, 5000L, "car");
        //ret [{}]:Car{carName='吉利帝豪', useAge=2, color='blue'}
        //logger.info("ret [{}]:" + car1);





        long endTime = System.currentTimeMillis();

        logger.info("Time elapsed:" + ((double)endTime - (double)startTime)/1000 + "s.");

        return JSON.toJSONString(new Object());
    }


    public void example1() throws ExecutionException, InterruptedException {
        CompletableFuture<String> f = CompletableFuture.supplyAsync(()->
             calledAsyncService.calledAsync("name")
        );

        CompletableFuture<String> exceptionally = f.whenComplete((t, u) -> {
            //do something
        }).exceptionally((e) -> "");

        String s = f.get();
    }

}
